#pragma once
#include <sqlite3.h>
#include <iostream>
#include <memory>


class SqliteHelper
{
    typedef int(*SqliteCallback)(void*, int, char**, char**);
public:
    SqliteHelper(const std::string& dbfile): _dbfile(dbfile), _handler(nullptr) {}

    // 封装sqlite3_open_v2(const char* filename, sqlite3** ppDb, int flags, const char* zVfs);
    bool open(int safe_level = SQLITE_OPEN_FULLMUTEX)
    {
        int ret = sqlite3_open_v2(_dbfile.c_str(), &_handler, 
        SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | safe_level, nullptr);

        if(ret != SQLITE_OK)
        {
            std::cout << "创建/打开sqlite数据库失败：";
            std::cout << sqlite3_errmsg(_handler) << std::endl;
            return false;
        }
        return true;
    }

    // 封装sqlite3_exec(sqlite3*, char* sql, 
    //         int(*callback)(void*, int, char**, char**), 
    //         void* arg, char** err)
    bool exec(const std::string& sql, SqliteCallback cb, void* arg)
    {
        std::unique_ptr<char[]> errmsg(new char[128]);
        char* errmsg_ptr = errmsg.get();
        int ret = sqlite3_exec(_handler, sql.c_str(), cb, arg, &errmsg_ptr);

        if(ret != SQLITE_OK)
        {
            std::cout << sql << std::endl;
            std::cout << "执行语句失败：" << errmsg_ptr << std::endl;
            //std::cout << sqlite3_errmsg(_handler) << std::endl;
            return false;
        }
        return true;
    }

    // 封装sqlite_close_v2(sqlite3*)
    void close()
    {
        if(_handler) { sqlite3_close_v2(_handler); }
    }
private:
    std::string _dbfile;
    sqlite3* _handler;
};
